Skip to content

feat: add the streaming-reveal extension to @tiptap/ai-toolkit - #8109

Open
ozdemircibaris wants to merge 18 commits into
mainfrom
feat/streaming-reveal-extension
Open

feat: add the streaming-reveal extension to @tiptap/ai-toolkit#8109
ozdemircibaris wants to merge 18 commits into
mainfrom
feat/streaming-reveal-extension

Conversation

@ozdemircibaris

Copy link
Copy Markdown
Contributor

Fixes

N/A (new feature)

Changes and Review

  • Adds the AiInsertReveal extension (@tiptap/ai-toolkit/streaming-reveal): fades in text as the AI streams it into a collaborative document.
  • View-only decorations from Yjs insert deltas, so it adds no marks and does not mutate the document. Requires the Collaboration extension.
  • Verify with the streaming demo (revealAiText) or streaming-reveal.spec.ts.

Checklist

  • I have added a changeset if necessary.
  • I have added tests if possible.
  • I have made sure to test my changes myself.

Responsibility

  • I have reviewed and understand these changes, and I take responsibility for this PR, even if an AI agent created it.

@ozdemircibaris
ozdemircibaris requested a review from a team as a code owner July 22, 2026 11:32
@changeset-bot

changeset-bot Bot commented Jul 22, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c03e2d5

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@tiptap/ai-toolkit Minor
@tiptap/server-ai-toolkit Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@netlify

netlify Bot commented Jul 22, 2026

Copy link
Copy Markdown

Deploy Preview for tiptap-embed ready!

Name Link
🔨 Latest commit c03e2d5
🔍 Latest deploy log https://app.netlify.com/projects/tiptap-embed/deploys/6a79cd2173af670008ffed82
😎 Deploy Preview https://deploy-preview-8109--tiptap-embed.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Summary

Adds AiInsertReveal to @tiptap/ai-toolkit to fade in AI-streamed text in collaborative documents.

  • Adds the @tiptap/ai-toolkit/streaming-reveal export.
  • Uses view-only decorations and does not change the document or add marks.
  • Reveals only remote Yjs inserts and ignores local typing.
  • Limits reveal ranges and removes them after durationMs.
  • Requires the Collaboration extension with optional Yjs dependencies.
  • Includes tests and a minor-release changeset.

Walkthrough

Adds AiInsertReveal to fade in AI-authored remote Yjs insertions with configurable styling and duration. The package builds and exports the new entry point, declares optional collaboration peers, and adds validation coverage plus a minor changeset.

Changes

Streaming reveal

Layer / File(s) Summary
Reveal tracking and decorations
packages/ai-toolkit/src/streaming-reveal.ts
Tracks remote Yjs inserts, identifies AI authors, resolves valid ranges, and renders temporary inline decorations.
Collaborative behavior validation
packages/ai-toolkit/src/streaming-reveal.spec.ts
Tests configuration, remote and local edits, decoration ranges, expiration, size limits, collaborator filtering, stale spans, and cleanup.
Build and package publication
packages/ai-toolkit/tsup.config.ts, packages/ai-toolkit/package.json, .changeset/new-pots-admire.md
Builds and exports streaming-reveal, declares optional collaboration peers, and records a minor release.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RemoteYjsDoc
  participant AiInsertReveal
  participant TiptapEditor
  RemoteYjsDoc->>AiInsertReveal: Apply remote Yjs insertion
  AiInsertReveal->>AiInsertReveal: Track AI-authored inserted run
  AiInsertReveal->>TiptapEditor: Schedule decoration render
  TiptapEditor->>AiInsertReveal: Resolve relative positions
  AiInsertReveal-->>TiptapEditor: Render fading inline decoration
Loading

Suggested labels: area: ai, area: editor, area: core, complexity: expert

Suggested reviewers: bdbch, alexvcasillas, arnaugomez

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed The description includes all required sections and explains the feature, verification method, changeset, and tests; only the self-testing checklist item remains unchecked.
Title check ✅ Passed The title clearly and concisely describes adding the streaming-reveal extension to @tiptap/ai-toolkit.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added area: ai Related to AI/LLM features area: editor Editor behavior, commands, and transactions complexity: hard Multiple components, research needed impact: low No direct user impact labels Jul 22, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/ai-toolkit/src/streaming-reveal.spec.ts (1)

157-167: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider fake timers for the expiry test.

This test relies on real wall-clock delays (30ms duration + 60ms wait) to prove expiry. It'll pass most of the time, but could get flaky on a slow/loaded CI runner. vi.useFakeTimers() + vi.advanceTimersByTime() (or mocking Date.now) would make it deterministic.

As per coding guidelines, "Add or update unit tests for deterministic user-visible behavior, preferring unit tests over end-to-end tests when appropriate."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ai-toolkit/src/streaming-reveal.spec.ts` around lines 157 - 167,
Update the “drops the reveal once its duration has elapsed” test to use Vitest
fake timers instead of real setTimeout delays. Enable fake timers before
creating the editor, advance them beyond the configured duration to trigger
expiry, assert the decoration is removed, and restore real timers afterward.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/ai-toolkit/src/streaming-reveal.spec.ts`:
- Around line 157-167: Update the “drops the reveal once its duration has
elapsed” test to use Vitest fake timers instead of real setTimeout delays.
Enable fake timers before creating the editor, advance them beyond the
configured duration to trigger expiry, assert the decoration is removed, and
restore real timers afterward.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: d98bc6de-cc92-432c-96ad-6088a795f294

📥 Commits

Reviewing files that changed from the base of the PR and between a963d48 and 326505e.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (5)
  • .changeset/new-pots-admire.md
  • packages/ai-toolkit/package.json
  • packages/ai-toolkit/src/streaming-reveal.spec.ts
  • packages/ai-toolkit/src/streaming-reveal.ts
  • packages/ai-toolkit/tsup.config.ts

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 22, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 22, 2026
bdbch
bdbch previously approved these changes Jul 23, 2026

@bdbch bdbch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM just a few nitpicks around comment lengths

Comment thread packages/ai-toolkit/src/streaming-reveal.ts Outdated
Comment thread packages/ai-toolkit/src/streaming-reveal.ts Outdated
@ozdemircibaris
ozdemircibaris dismissed stale reviews from bdbch and coderabbitai[bot] via d6da91e July 23, 2026 12:17
@coderabbitai coderabbitai Bot added complexity: medium Moderate change, possibly multiple files and removed area: editor Editor behavior, commands, and transactions complexity: hard Multiple components, research needed labels Jul 23, 2026
@coderabbitai coderabbitai Bot added complexity: hard Multiple components, research needed impact: low No direct user impact and removed complexity: medium Moderate change, possibly multiple files labels Jul 24, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 24, 2026
@ozdemircibaris
ozdemircibaris requested a review from bdbch August 5, 2026 09:02

@bdbch bdbch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - just a verification question

Comment thread packages/ai-toolkit/package.json
bdbch
bdbch previously approved these changes Aug 7, 2026

@bdbch bdbch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some more comments

) => {
// Only remote edits, i.e. the AI. The local user's own typing is a
// local transaction and must not fade.
if (transaction.local) return

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really only AI? What about collaborative changes that are not local transactions? I think this needs an transaction.origin filter as well to make sure that collab changes don't go through this reveal feature.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aah good point, it’s not only the AI. local === false just means the update came from applyUpdate, so other collaborators fade too. An origin filter won’t help though: Hocuspocus applies every remote update with the provider as origin, and origin isn’t sent over the wire. Only the clientID on the inserted items can tell AI and human edits apart. I’ll fix the comment for now. We can add clientID filtering if we want it strictly AI only

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Imho we would need to make sure that this is AI only - otherwise collaborative changes from other users would be run through the same reveal logic, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's AI only right now <3

Comment thread packages/ai-toolkit/src/streaming-reveal.ts Outdated
}

/** Limits each revealed streamed insert to guard against mis-resolved positions spanning the document. */
const MAX_REVEAL_RANGE = 400

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can see content that exceeds the range just is silently dropping the run (correct me if I'm wrong).

should we just clamp the reveal to those characters and make sure the whole run still completes afterwards?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You were right, the old code dropped the whole run. fixed thanks!

@ozdemircibaris
ozdemircibaris dismissed stale reviews from bdbch and coderabbitai[bot] via 6711609 August 7, 2026 14:52
@coderabbitai coderabbitai Bot added area: core Core editor engine and ProseMirror integration complexity: expert Deep domain knowledge required, high risk and removed complexity: hard Multiple components, research needed impact: low No direct user impact labels Aug 7, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/ai-toolkit/src/streaming-reveal.spec.ts (1)

63-78: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Move this test file under an __tests__ directory.

packages/ai-toolkit/src/streaming-reveal.spec.ts is outside the required test path. Place it under packages/**/__tests__/ to follow the repository test layout.

As per coding guidelines, "Use Vitest tests under packages/**/__tests__/."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ai-toolkit/src/streaming-reveal.spec.ts` around lines 63 - 78, Move
the streaming-reveal test file containing revealDecorations into a
packages/**/__tests__/ directory, preserving its existing test contents and
behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/ai-toolkit/src/streaming-reveal.spec.ts`:
- Around line 63-78: Move the streaming-reveal test file containing
revealDecorations into a packages/**/__tests__/ directory, preserving its
existing test contents and behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: e63e3bc8-b957-492e-8c0e-cc16dc6a3533

📥 Commits

Reviewing files that changed from the base of the PR and between 696d2cf and 6711609.

📒 Files selected for processing (2)
  • packages/ai-toolkit/src/streaming-reveal.spec.ts
  • packages/ai-toolkit/src/streaming-reveal.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/ai-toolkit/src/streaming-reveal.ts

coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 7, 2026
@ozdemircibaris
ozdemircibaris requested a review from bdbch August 7, 2026 16:35
@bdbch

bdbch commented Aug 10, 2026

Copy link
Copy Markdown
Member

@ozdemircibaris I'd like to clarify the open questions before going forward.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/ai-toolkit/src/streaming-reveal.spec.ts`:
- Around line 1-9: Move the test containing the AiInsertReveal tests from its
current src location into packages/ai-toolkit/__tests__/, then update its
relative AiInsertReveal import to resolve from the new directory while
preserving the existing test setup and cases.
- Around line 214-220: Control timing in the streaming reveal tests: at
packages/ai-toolkit/src/streaming-reveal.spec.ts lines 214-220, enable Vitest
fake timers and set a fixed system time before both remoteInsert calls so their
animation offsets are deterministic; at lines 359-363, replace the real
setTimeout wait with advancing fake timers beyond durationMs, preserving the
existing assertions and cleanup.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 609a509b-1029-4362-86e3-260393568105

📥 Commits

Reviewing files that changed from the base of the PR and between eded5e4 and 22d0b32.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (5)
  • .changeset/new-pots-admire.md
  • packages/ai-toolkit/package.json
  • packages/ai-toolkit/src/streaming-reveal.spec.ts
  • packages/ai-toolkit/src/streaming-reveal.ts
  • packages/ai-toolkit/tsup.config.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/ai-toolkit/tsup.config.ts
  • .changeset/new-pots-admire.md
  • packages/ai-toolkit/package.json
  • packages/ai-toolkit/src/streaming-reveal.ts

Comment thread packages/ai-toolkit/src/streaming-reveal.spec.ts Outdated
Comment thread packages/ai-toolkit/__tests__/streaming-reveal.spec.ts
* The collaboration provider, e.g. `HocuspocusProvider` or `TiptapCloudProvider`.
* Its awareness is what identifies the AI, so nothing is revealed without it.
*/
provider: any

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we be able to look into the editor options / settings to find out if collaboration is enabled and find the provider from there? That way the user wouldn't need to pass it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually collaboration has a provider option but the extension never reads it and nothing in the repo passes it. So in practice we can only find the provider when CollaborationCaret is used. Not everyone uses the caret, so we would still need the option. I would keep it explicit for now

coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: ai Related to AI/LLM features area: core Core editor engine and ProseMirror integration area: editor Editor behavior, commands, and transactions complexity: expert Deep domain knowledge required, high risk

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants